/*
    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/


/**
 * \file c_Morse.h
 * \brief  Expression Morse
 * \author Jos de Jong
 * \date 2007-12-22
 */


#ifndef msMorse_H
#define msMorse_H
#include <msScalarFunction.h>

namespace atomism
{


class msMorse : public msScalarFunction
{
      //!\name from msRegister 
      //@{
      static msRegistrar Registrar;
      static bool  isMorseRegisteredInPython;
      static msRegister* createInstance() { return new msMorse; }
      //@}   
      
      
protected:
  
       void registryInPython();
      
       void initialize()  { 
             msScalarFunction::initialize();
             };
	     
       void update(){
	     msScalarFunction::update();
             }
             
       msMorse() : msScalarFunction(){
	     constructVar("msMorse","msMorse","morse");
	     setConstant("a",2.4);
	     setConstant("pow",2);
	     setConstant("De",100);
	     setConstant("re",1.1);
	     }    
   
public:
        
       enum TOKENTYPE {NOTHING = -1, DELIMETER, NUMBER, VARIABLE, FUNCTION, UNKNOWN};
	

       static boost::shared_ptr<msMorse> New( ){
	    
	       boost::shared_ptr<msMorse> T( new msMorse );
	       T->initialize(); 
	       T->getYUnit().set("kcal/mol");
	       T->update();
	       return T;
	       }

	virtual boost::shared_ptr<msTreeMapper> clone() { 

            boost::shared_ptr<msMorse> clone = New(); 
	    clone->msTreeMapper::operator=(*this);					      
	    return clone;
            }  
	
	double evaluate(){ double r=0; 
			   double q0 =  (*getCoordinates())[0]->Value;
		           double a = Constants["a"];
	 		   double b = Constants["pow"];
 			   double De= Constants["De"];
			   double re= Constants["re"];
			   if( q0 < re) r =  De * pow( ( 1 - exp( - a * ( q0 - re ) )), 2 );
			   if( q0 >= re)  r =  De * pow( ( 1 - exp( - a * ( q0 - re ) )), b );
			   return r;
			   }
		            
      	std::string getLabel(){return ("Morse for N2");}
        
 private:
	
	double a;
	double De;
	double re;
	
};


class msGMP : public msScalarFunction
{
      //!\name from msRegister 
      //@{
      static msRegistrar Registrar;
      static bool  isGMPRegisteredInPython;
      static msRegister* createInstance() { return new msGMP; }
      //@}   
      
      
protected:
  
       void registryInPython();
      
       void initialize()  { 
             msScalarFunction::initialize();
             };
	     
       void update(){
	     msScalarFunction::update();
             }
             
       msGMP() : msScalarFunction(){
	     constructVar("msGMP","msGMP","GMP");
	     setConstant("a",2.4);
	     De=230;
	     re=1.1;
	     }    
   
public:
        
       enum TOKENTYPE {NOTHING = -1, DELIMETER, NUMBER, VARIABLE, FUNCTION, UNKNOWN};
	
       static boost::shared_ptr<msGMP> New( ){
	    
	       boost::shared_ptr<msGMP> T( new msGMP );
	       T->initialize(); 
	       T->getYUnit().set("kcal/mol");
	       T->update();
	       return T;
	       }

	virtual boost::shared_ptr<msTreeMapper> clone() { 

            boost::shared_ptr<msGMP> clone = New(); 
	    clone->msTreeMapper::operator=(*this);					      
	    return clone;
            }  
	
	double evaluate(){ double q0 =  (*getCoordinates())[0]->Value;
		           double a = Constants["a"];
	 		   double b = exp(a*re)-1;
 
			   double r = De * pow( 1- b / (exp(a*q0)-1), 2);
			   if(r>100) r = 100.;
			   return r;
			   }
		            
      	std::string getLabel(){return ("GMP for N2");}
        
 private:
	
	double a;
	double De;
	double re;
	
};

}
#endif // msMorse_H






